import copy


def default_error():
    a1 = [1, 2, 3]  # 创建一个列表：可变数据类型
    b1 = a1  # b 和 a 引用同一个列表（它们指向同一内存地址）
    b1[0] = 3  # 由于 a 和 b 引用同一个列表，修改 b 会影响 a
    print(a1)  # 输出： [3, 2, 3]


def use_list_copy():
    '''
    使用列表自带的copy()   浅拷贝
    :return:
    '''
    a2 = [1, 2, 3]  # 创建一个列表：可变数据类型
    b2 = a2.copy()
    b2[0] = 3  # 修改 b 不会影响 a
    print(a2)  # 输出： [1, 2, 3]


def use_copy():
    '''
    使用copy包中的copy
    :return:
    '''
    c = [1, 2, 3]
    d = copy.copy(c)
    d[0] = 4
    print(id(c), c)
    print(id(d), d)


def use_copy2():
    '''
    copy是浅copy，只做一层空间copy，即a和b是复制出来的，但是a和b的值不是复制的
    :return:
    '''
    a = [1, 2]
    b = [3, 4]
    c = [a, b]
    d = copy.copy(c)
    print(f'c=[a,b]:{id(c)}, {c}')
    print(f'd=[a,b]:{id(d)}, {d}')
    print('改变a')
    a[0] = 10
    print(f'c=[a,b]:{id(c)}, {c},c/d都改变')
    print(f'd=[a,b]:{id(d)}, {d},c/d都改变')
    print('-' * 50)
    print(f'id(c[0]){id(c[0])},id(d[0]){id(d[0])}')
    print(f'id(c[1]){id(c[1])},id(d[1]){id(d[1])}')


def use_deepcopy():
    '''
    deepcopy递归的copy，不管有多少层都新做一个空间
    :return:
    '''
    a = [1, 2]
    b = [3, 4]
    c = [a, b]
    d = copy.deepcopy(c)
    print(f'c=[a,b]:{id(c)}, {c}')
    print(f'd=[a,b]:{id(d)}, {d}')
    print('改变a')
    a[0] = 10
    print(f'c=[a,b]:{id(c)}, {c},c改变')
    print(f'd=[a,b]:{id(d)}, {d},d不改变')
    print('-' * 50)
    print(f'id(c[0]){id(c[0])},id(d[0]){id(d[0])}地址不同')
    print(f'id(c[1]){id(c[1])},id(d[1]){id(d[1])}地址不同')


class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.wear = ['t恤', '鞋子']


def use_copy_own_obj():
    '''
    实际对于自定义对象的练习
    :return:
    '''
    old = Student('小明', 18)
    new = copy.deepcopy(old)
    new.age = 20  # 新对象修改后原对象不会有影响
    new.wear.append('裤子')  # 新对象修改后原对象不会有影响
    print(old.name, old.age, old.wear)  # 旧的int型不会改变，但是列表（可变类型）浅拷贝会改变，深拷贝不改变


if __name__ == '__main__':
    # default_error()
    # use_list_copy()
    # use_copy()
    # use_copy2()
    # use_deepcopy()
    use_copy_own_obj()
